package cn.chendd.api.hello.controller;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import io.swagger.annotations.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ContentDisposition;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Hello示例Controller定义
 *
 * @author chendd
 * @date 2022/12/26 14:54
 */
@RestController
@RequestMapping(value = "/hello" , produces = MediaType.APPLICATION_JSON_VALUE)
@Api(tags = "Hello 示例 测试")
@ApiSort(20)
public class HelloExampleController {

    @ApiOperationSupport(order = 10)
    @ApiOperation(value = "数据列表" , notes = "获取数据列表")
    @GetMapping("/list")
    public List<Point> getList() {
        return Lists.newArrayList(new Point(1 , 1) , new Point(2 , 2) , new Point(3 , 3));
    }

    @ApiOperationSupport(order = 10)
    @ApiOperation(value = "复杂数据结构" , notes = "获取复杂数据结构列表")
    @GetMapping("/complex")
    public void complex(HttpServletResponse response) throws IOException {
        JSONObject result = new JSONObject();
        result.put("total" , 1005);
        JSONObject data = new JSONObject();
        data.put("x" , "88");
        data.put("y" , true);
        data.put("list" , this.getList());
        result.put("data" , data);
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.getWriter().println(result.toJSONString());
    }

    @ApiOperationSupport(order = 20)
    @ApiOperation(value = "sayHello" , notes = "根据名称sayHello")
    @GetMapping("/world/{name}")
    public String sayHello(@ApiParam(name = "name" , value = "名称") @PathVariable String name) {
        Logger logger = LoggerFactory.getLogger(HelloExampleController.class);
        String result = String.format("hello , %s", name);
        logger.info(result);
        return result;
    }

    @ApiOperationSupport(order = 25)
    @ApiOperation(value = "form参数" , notes = "使用x-www-form-urlencoded获取参数")
    @PostMapping(value = "/form" , consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public String sayHello(@ApiParam(name = "name" , value = "名称") @RequestParam String name ,
                           @ApiParam(name = "value" , value = "value值") @RequestParam String value ,
                           @ApiParam(name = "author" , value = "author值（header）" , required = false)
                           @RequestHeader(name = "author" , required = false) String author) {
        return String.format("name = %s , value = %s , header author = %s" , name , value , author);
    }

    @ApiOperationSupport(order = 30)
    @ApiOperation(value = "请求参数" , notes = "传递url参数和request body参数")
    @PutMapping("/param_body")
    public String paramBody(@ApiParam(name = "name" , value = "名称") @RequestParam String name ,
                            @ApiParam(name = "body" , value = "json格式String") @RequestBody String body) {
        return String.format("hello , name = %s , body = %s" , name , body);
    }

    @ApiOperationSupport(order = 40)
    @ApiOperation(value = "下载yaml文件" , notes = "下载yaml文件")
    @PostMapping(value = "/download_yaml" , produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public void downloadYaml(HttpServletResponse response) throws IOException {
        File file = new File(getClass().getResource("/application.yaml").getFile());
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION , ContentDisposition.attachment().filename(file.getName()).build().toString());
        response.setHeader(HttpHeaders.CONTENT_LENGTH , String.valueOf(file.length()));
        try (ServletOutputStream outputStream = response.getOutputStream();
             InputStream inputStream = new FileInputStream(file)){
            StreamUtils.copy(inputStream , outputStream);
        }
    }

    @ApiOperationSupport(order = 50)
    @ApiOperation(value = "下载图片" , notes = "下载swagger-jar中的图片")
    @GetMapping(value = "/download_image" , produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public void download(HttpServletResponse response) throws IOException {
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION , ContentDisposition.attachment().filename("icon.png").build().toString());
        try (ServletOutputStream outputStream = response.getOutputStream();
                          InputStream inputStream = getClass().getResourceAsStream("/META-INF/resources/webjars/bycdao-ui/layer3.0.3/skin/default/icon.png")){
             StreamUtils.copy(inputStream , outputStream);
        }
    }

    @ApiOperationSupport(order = 55)
    @ApiOperation(value = "下载文件" , notes = "下载本地路径中的文件（验证大文件、中文文件名）" , consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    @PostMapping(value = "/download_file" , consumes = MediaType.ALL_VALUE, produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public void download(@ApiParam(name = "filePath" , value = "文件路径") @RequestBody String filePath ,
                         HttpServletResponse response) throws IOException {
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        File file = new File(filePath);
        //示例只处理个别浏览器下载时显示中文
        String filename = new String(file.getName().getBytes(), StandardCharsets.ISO_8859_1);
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION , ContentDisposition.attachment().filename(filename).build().toString());
        response.setHeader(HttpHeaders.CONTENT_LENGTH , String.valueOf(file.length()));
        try (ServletOutputStream outputStream = response.getOutputStream();
             InputStream inputStream = new FileInputStream(file)){
             StreamUtils.copy(inputStream , outputStream);
        }
    }

    @ApiOperationSupport(order = 60)
    @ApiOperation(value = "文件上传" , notes = "根据参数处理文件上传")
    @PostMapping(value = "/upload" , consumes = MediaType.MULTIPART_FORM_DATA_VALUE , produces = MediaType.APPLICATION_JSON_VALUE)
    public Map<String , Object> upload(@ApiParam(name = "files" , value = "上传文件") List<MultipartFile> files , @ApiParam(name = "param" , value = "其它参数") UploadParam param) {
        Map<String , Object> paramMap = Maps.newHashMap();
        paramMap.put("id" , param.getId());
        paramMap.put("name" , param.getName());
        paramMap.put("nikeNames" , param.getNikeNames());
        if (files != null && !files.isEmpty()) {
            paramMap.put("files" , files.stream().map(MultipartFile::getOriginalFilename).collect(Collectors.toList()));
        }
        return paramMap;
    }

    /**
     * 文件上传参数
     */
    public static class UploadParam {

        @ApiModelProperty("id")
        private Integer id;

        @ApiModelProperty("名称")
        private String name;

        @ApiModelProperty("昵称[]")
        private String[] nikeNames;

        public Integer getId() {
            return id;
        }

        public void setId(Integer id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String[] getNikeNames() {
            return nikeNames;
        }

        public void setNikeNames(String[] nikeNames) {
            this.nikeNames = nikeNames;
        }
    }

}
